Monografias.com > Sin categoría
Descargar Imprimir Comentar Ver trabajos relacionados

Programación concurrente en lenguajes funcionales (página 2)




Enviado por Pablo Turmero



Partes: 1, 2

Monografias.com

9
Ejemplo1:
import Control.Concurrent
main = forkIO (escribir 'a') >> escribir 'b'
where escribir c = putChar c >> escribir c

Monografias.com

10
características de forkIO :
Como la implementación de haskell usa evaluación perezosa, forkIO necesitará sincronización entre procesos, ya que un proceso puede intentar evaluar un razonamiento que ya está siendo evaluado por otro proceso, en cuyo caso el primero debe ser bloqueado hasta que el último complete la evaluación y sobrescriba el razonamiento con su valor.
Como tanto el proceso padre como el hijo, pueden cambiar el mismo estado compartido forkIO introduce inmediatamente el no determinismo. El problema es que casi todas las aplicaciones concurrentes interesantes implican el uso del mismo estado compartido por varios procesos. Por tanto, la solución correcta será proveer mecanismos que permitan la gestión segura de un estado compartido.
forkIO es asimétrico. Cuando un proceso ejecuta un forkIO crea un proceso hijo que se ejecuta concurrentemente al padre.

Monografias.com

11
2.2 Sincronización y comunicación
Los procesos pueden necesitar acceso exclusivo a algunos objetos como por ejemplo ficheros. La manera de implementar este acceso exclusivo requiere una variable compartida mutable o un semáforo.
Para que un proceso pueda leer una cadena de valores producida por varios procesos es proporcionando una operación no determinista de ordenación.

Monografias.com

12
Type MVar a
Un valor del tipo MVar t, para algún tipo t, es el nombre de una posición de memoria que pueda estar vacía o contener un valor de tipo t. A su vez sobre MVar se pueden realizar las siguientes operaciones:
newMVar :: IO (MVar a) Crea una nueva MVar
takeMVar :: MVar a -> IO a Bloquea hasta que la posición sea no vacía. Entonces lee y devuelve el valor dejando la posición vacía.
putMVar :: MVar a -> a -> IO () Escribe un valor en la posición especificada. Si existen uno o mas procesos bloqueados en takeMVar sobre dicha variable, se selecciona uno para que lo procese. Puede producir error utilizarlo sobre una variable que ya contenga un valor.

Monografias.com

13
MVar
El tipo MVar puede ser usado de tres maneras diferentes:
Puede ser usado como una versión sncronizada del tipo MutVar.
Puede ser empleado como un tipo de canal, donde takeMVar y PutMVar funcionan como recibir y enviar.
El MVar puede ser usado como un semáforo binario, donde los signal y los waits son implementados con putMVar y takeMVar respectivamente.

Monografias.com

14
2.3 Semáforos
Aunque se puede implementar con un MVar usando
las operaciones putMVar y takeMVar, los semáforos tambien están implementados en Concurrent Haskell.
Semáforo binario:
data QSem
newQSem :: Int -> IO QSem
waitQSem :: QSem -> IO ()
signalQSem :: QSem -> IO ()

Monografias.com

15
2.3 Semáforos
Semáforos de cantidad general:
data QSemN
newQSemN :: Int -> IO QSemN
waitQSemN :: QSemN -> Int -> IO ()
signalQSemN :: QSemN -> Int -> IO ()

Monografias.com

16
2.4 Otras operaciones concurrentes
forkIO :: IO a -> IO –Crea proceso hijo
threadDelay :: Int -> IO () – Dormir durante n microsegundos
newEmptyMVar :: IO (MVar a) – Crear Mvar vacío
newMVar :: a -> IO (MVar a) – Inicializar MVAr
takeMVar :: MVar a -> IO a – take bloqueante
putMVar :: MVar a -> a -> IO () – put bloqueante
tryTakeMVar :: MVar a -> IO (Maybe a) – take no bloqueante
tryPutMVar :: MVar a -> a -> IO Bool – put no bloqueante
isEmptyMVar :: MVar a -> IO Bool — Test de Mvar vacío
swapMVar :: MVar a -> a -> IO a — Intercambia el valor de Mvar

Monografias.com

17
2.5 Productor/consumidor
MVar puede ser usado para implementar una conexión entre productor y consumidor. El productor guarda elementos en el MVar y el consumidor los saca. El problema es que no hay nada que impida que el productor escriba un segundo valor antes de que el consumidor haya sacado el primero.
Este problema se soluciona con un segundo MVar para manejar confirmaciones entre consumidor y productor. Llamaremos a la abstracción resultante CVar (variable de canal).

Monografias.com

18
Productor consumidor
type CVar a = (MVar a, — Productor-> consumidor
MVar ()) — Consumidor -> productor

newCVar :: IO (CVar a)
newCVar = newMVar >>= data_var ->
newMVar >>= ack_var ->
putMVar ack_var () >> return (data_var, ack_var)

putCVar :: CVar a -> a -> IO ()
putCVar (data_var,ack_var) val= takeMVar ack_var >> putMVar data_var val

getCVar :: CVar a -> IO a
getCVar (data_var,ack_var) = takeMVar data_var >>= val ->
putMVar ack_var () >> return val

Monografias.com

19
2.6 Canales
El proceso creado por el forkIO y su padre pueden realizar entrada y salida independientemente. Podemos pensar en el estado del sistema como un objeto conmutable compartido. Por ejemplo, si dos procesos escriben en el mismo fichero pueden aparecer situaciones indeseadas. Pero como ya sabemos, es común que dos o más procesos quieran acceder al mismo fichero.

Monografias.com

20
Canales
Usando MVar’s podemos definir un nuevo tipo que llamaremos canal que permitirá que múltiples procesos escriban y lean de él de forma segura.
type Channel a = (MVar (Stream a), — Último leído
MVar (Stream a)) — Último escrito
newChan :: IO (Channel a)
putChan :: Channel a -> a -> IO
getChan :: Channel a -> IO a

Monografias.com

21
Canales

Monografias.com

22
El canal está implementado por un par de MVar’s que apuntan al último elemento leído (read end) y al último elemento escrito (write end) del canal respectivamente.
Las Mvar del canal proporcionan un mecanismo mediante el cual las operaciones de put y get pueden modificar el read end y el write end del canal.
Los datos en el buffer son almacenados en un Stream que es un MVar que puede estar vacío (en cuyo caso no hay datos en el stream) o almacena un Item.

Monografias.com

23
type Stream a = MVar (Item a)
Un Item es simplemente un par de elementos, uno con el dato y otro apundanto al resto del stream.
data Item a = MkItem a (Stream a)
Un Stream puede ser considerado como una lista que consiste en alternar Items y Mvars que termina con un “agujero” que consiste en un MVar vacío. El Write end del canal apunta a dicho “agujero”(Hole).

Monografias.com

24
newChan = do { read < – newEmptyMVar ;
write < – newEmptyMVar ;
hole < – newEmptyMVar ;
putMVar read hole ;
putMVar write hole ;
return (read,write) }

Monografias.com

25
putChan (read,write) val
= do { new_hole < – newEmptyMVar ;
old_hole < – takeMVar write ;
putMVar write new_hole ;
putMVar old_hole (MkItem val new_hole) }

Monografias.com

26
getChan (read,write)
= do { head_var < – takeMVar read ;
MkItem val new_head < – takeMVar head_var ;
putMVar read new_head ;
return val }

Monografias.com

27
canal multicast

dupChan :: Channel a -> IO (Channel a)

dupChan (read,write)
= do { new_read < – newEmptyMVar ;
hole < – readMVar write ;
putMVar new_read hole ;
return (new_read, write) }

Monografias.com

28
Implementación de canales en Concurrent Haskell
data Chan a
newChan :: IO (Chan a) — Nuevo canal
writeChan :: Chan a -> a -> IO () –Escribe dato en canal
readChan :: Chan a -> IO a –Lee un dato del canal
dupChan :: Chan a -> IO (Chan a) –Duplica el canal
unGetChan :: Chan a -> a -> IO () –Devuelve un dato al canal
isEmptyChan :: Chan a -> IO Bool –Comprueba si está vacío
getChanContents :: Chan a -> IO [a] — lee todo el contenido
writeList2Chan :: Chan a -> [a] -> IO () — Escribe el contenido de una lista en el canal

Monografias.com

29
3. CONCLUSIONES
Hemos comprobado como Concurrent Haskell aporta nueva funcionalidad a Haskell.
Añadiendo forkIO y MVars a Haskell damos un salto cualitativo en cuanto a la cantidad de aplicaciones que podemos escribir. Las extensiones son sencillas y simples de describir.
En la actualidad Haskell y sus versiones concurrentes están siendo empleados de manera comercial como herramienta de programación para servidores, aportando una nueva manera de programar potente y elegante.

Monografias.com

30
4. REFERENCIAS
http://www.haskell.org
Ruíz, B.C.; Gutiérrez, F.; Guerrero, P.; Gallardo, J.E.: Razonando con Haskell. Una introducción a la Programación Funcional. Servicio reprogr. (OCÉ) E.T.S.I.I., Universidad de Málaga. 2000
http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control.Concurrent.html
Tackling the Awkward Squad: monadic input/output, concurrency, exceptions, and foreign-language calls in Haskell
Simon PEYTON JONES Microsoft Research, Cambridge simonpj@microsoft.com
http://research.microsoft.com/users/simonpj
Concurrent Haskell
Simon Peyton Jones (University of Glasgow)
Andrew Gordon (University of Cambridge)
Sigbjorn Finne (University of Glasgow)
Notas para la asignatura Programación Declarativa Avanzada.
Blas Carlos Ruiz Jiménez

Partes: 1, 2
 Página anterior Volver al principio del trabajoPágina siguiente 

Nota al lector: es posible que esta página no contenga todos los componentes del trabajo original (pies de página, avanzadas formulas matemáticas, esquemas o tablas complejas, etc.). Recuerde que para ver el trabajo en su versión original completa, puede descargarlo desde el menú superior.

Todos los documentos disponibles en este sitio expresan los puntos de vista de sus respectivos autores y no de Monografias.com. El objetivo de Monografias.com es poner el conocimiento a disposición de toda su comunidad. Queda bajo la responsabilidad de cada lector el eventual uso que se le de a esta información. Asimismo, es obligatoria la cita del autor del contenido y de Monografias.com como fuentes de información.

Categorias
Newsletter